<!---
Copyright: (c) 2006 The MachBlog Authors
Authors: Matt Woodward (mpwoodward@gmail.com) & Peter J. Farrell (pjf@maestropublishing.com)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. 
You may obtain a copy of the License at 

http://www.apache.org/licenses/LICENSE-2.0 

Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
See the License for the specific language governing permissions and 
limitations under the License.

$Id: NotificationService.cfc 1100 2007-02-26 16:58:52Z mpwoodward $

Notes:
--->
<cfcomponent
	displayname="NotificationService"
	output="false"
	hint="Performs all notifications.">

	<!---
	PROPERTIES
	--->
	<cfset variables.instance = StructNew() />
	<cfset variables.notificationConfigBean = "" />
	<cfset variables.udfs = "" />

	<!---
	INITIALIZATION / CONFIGURATION
	--->
	<cffunction name="init" access="public" returntype="NotificationService" output="false"
		hint="Initializes the service.">	
		<cfreturn this />
	</cffunction>

	<cffunction name="setNotificationConfigBean" access="public" returntype="void" output="false">
		<cfargument name="notificationConfigBean" type="NotificationConfig" 
				required="true" />
		<cfset variables.notificationConfigBean = arguments.notificationConfigBean />
	</cffunction>
	<cffunction name="getNotificationConfigBean" access="public" 
				returntype="NotificationConfig" output="false">
		<cfreturn variables.notificationConfigBean />
	</cffunction>

	<cffunction name="setUDFs" access="public" returntype="void" output="false">
		<cfargument name="udfs" type="machblog.org.machblog.utils.udfs"  required="true" />
		<cfset variables.udfs = arguments.udfs />
	</cffunction>
	<cffunction name="getUDFs" access="public" returntype="machblog.org.machblog.utils.udfs" output="false">
		<cfreturn variables.udfs />
	</cffunction>
	
	<cffunction name="getEmailBean" access="public" output="false" returntype="Email">
		<cfreturn createObject("component", "Email").init() />
	</cffunction>

	<!---
	PUBLIC FUNCTIONS
	--->
	<cffunction name="emailEntryToFriend" access="public" output="false" returntype="void" 
			hint="Sends an email containing the link to a blog post">
		<cfargument name="toEmail" type="string" required="true" />
		<cfargument name="fromEmail" type="string" required="true" />
		<cfargument name="emailSubject" type="string" required="true" />
		<cfargument name="emailBody" type="string" required="true" />
		
		<cfset var email = getEmailBean() />
		
		<cfset email.setToEmail(arguments.toEmail) />
		<cfset email.setFromEmail(arguments.fromEmail) />
		<cfset email.setSubject(arguments.emailSubject) />
		<cfset email.setBody(arguments.emailBody) />
		
		<cfset sendEmail(email) />
	</cffunction>
	
	<cffunction name="emailContactForm" access="public" output="false" returntype="void" 
			hint="Sends an email with the contents of the contact form">
		<cfargument name="fromName" type="string" required="true" />
		<cfargument name="fromEmail" type="string" required="true" />
		<cfargument name="comments" type="string" required="true" />
		<cfargument name="subject" type="string" required="true" />
		<cfargument name="toEmail" type="string" required="true" />
		
		<cfset var email = getEmailBean() />
		
		<cfset email.setToEmail(arguments.toEmail) />
		<cfset email.setFromEmail("#arguments.fromName# <#arguments.fromEmail#>") />
		<cfset email.setSubject(arguments.subject) />
		<cfset email.setBody(arguments.comments) />
		
		<cfset sendEmail(email) />
	</cffunction>
	
	<cffunction name="emailCommentNotification" access="public" output="false" returntype="void" 
			hint="Sends out email notifications of new comments to comment subscribers and to the blog admin">
		<cfargument name="fromAddress" type="string" required="true" />
		<cfargument name="toAddress" type="string" required="true" />
		<cfargument name="emailSubject" type="string" required="true" />
		<cfargument name="entryUrl" type="string" required="true" />
		<cfargument name="unsubscribeText" type="string" required="true" />
		<cfargument name="unsubscribeUrl" type="string" required="true" />
		<cfargument name="commentByText" type="string" required="true" />
		<cfargument name="commenterName" type="string" required="true" />
		<cfargument name="comment" type="string" required="true" />
		
		<cfset var email = getEmailBean() />
		<cfset var emailBody = arguments.emailSubject & Chr(10) & Chr(13) & Chr(10) & Chr(13) & 
								arguments.entryUrl & Chr(10) & Chr(13) & Chr(10) & Chr(13) & 
								arguments.commentByText & " " & arguments.commenterName & ":" & 
								Chr(10) & Chr(13) & arguments.comment & Chr(10) & Chr(13) & Chr(10) & Chr(13) &
								arguments.unsubscribeText & Chr(10) & Chr(13) & arguments.unsubscribeUrl />
		
		<cfset email.setFromEmail(arguments.fromAddress) />
		<cfset email.setToEmail(arguments.toAddress) />
		<cfset email.setSubject(arguments.emailSubject) />
		<cfset email.setBody(emailBody) />
		
		<cfset sendEmail(email) />
	</cffunction>
	
	<cffunction name="emailEntryNotification" access="public" output="false" returntype="void">
		<cfargument name="fromAddress" type="string" required="true" />
		<cfargument name="subscribers" type="query" required="true" />
		<cfargument name="subject" type="string" required="true" />
		<cfargument name="entryTitle" type="string" required="true" />
		<cfargument name="entryUrl" type="string" required="true" />
		<cfargument name="unsubscribeMessage" type="string" required="true" />
		<cfargument name="unsubscribeUrl" type="string" required="true" />
		
		<cfset var email = getEmailBean() />
		<cfset var emailBody = arguments.subject & Chr(10) & Chr(13) & Chr(10) & Chr(13) & """#arguments.entryTitle#"""  
								& Chr(10) & Chr(13) & arguments.entryUrl & Chr(10) & Chr(13) & Chr(10) & Chr(13) 
								& arguments.unsubscribeMessage & Chr(10) & Chr(13) & arguments.unsubscribeUrl />
		
		<cfset email.setFromEmail(arguments.fromAddress) />
		<cfset email.setSubject(arguments.subject) />
		
		<cfloop query="arguments.subscribers">
			<cfset email.setBody(emailBody & arguments.subscribers.subscriber_email) />
			<cfset email.setToEmail(arguments.subscribers.subscriber_email) />
			<cfset sendEmail(email) />
		</cfloop>
	</cffunction>
	
	<cffunction name="emailNewPassword" access="public" output="false" returntype="void">
		<cfargument name="toEmail" type="string" required="true" />
		<cfargument name="fromEmail" type="string" required="true" />
		<cfargument name="emailSubject" type="string" required="true" />
		<cfargument name="emailBody" type="string" required="true" />
		<cfargument name="newPassword" type="string" required="true" />
		
		<cfset var email = getEmailBean() />
		<cfset arguments.emailBody = arguments.emailBody & Chr(10) & Chr(13) & Chr(10) & Chr(13) & arguments.newPassword />
		
		<cfset email.setFromEmail(arguments.fromEmail) />
		<cfset email.setToEmail(arguments.toEmail) />
		<cfset email.setSubject(arguments.emailSubject) />
		<cfset email.setBody(arguments.emailBody) />
		
		<cfset sendEmail(email) />
	</cffunction>
	
	<cffunction name="emailSubscribers" access="public" output="false" returntype="void" 
			hint="Emails blog subscribers">
		<cfargument name="fromEmail" type="string" required="true" />
		<cfargument name="subject" type="string" required="true" />
		<cfargument name="body" type="string" required="true" />
		<cfargument name="subscribers" type="query" required="true" />
		
		<cfset var email = getEmailBean() />
		
		<cfset email.setFromEmail(arguments.fromEmail) />
		<cfset email.setSubject(arguments.subject) />
		<cfset email.setBody(arguments.body) />
		
		<cfloop query="arguments.subscribers">
			<cfset email.setToEmail(arguments.subscribers.subscriber_email) />
			<cfset sendEmail(email) />
		</cfloop>
	</cffunction>
	
	<!--- GENERIC NOTIFICATION METHODS --->
	<cffunction name="sendEmail" access="public" output="false" returntype="void" 
			hint="Sends an email using the EmailBean passed in">
		<cfargument name="email" type="Email" required="true" />
		
		<!--- I was running into issues on my smtp server--if I had the username and password attributes 
				are in the cfmail tag, but they're blank, the smtp server refuses with an 'authentication failed' 
				error, so I'm putting a conditional here and two sets of cfmail tags. --->
		<cfif getNotificationConfigBean().getSmtpUsername() is "" and 
				getNotificationConfigBean().getSmtpPassword() is "">
			<cfmail from="#arguments.email.getFromEmail()#" 
					to="#arguments.email.getToEmail()#" 
					subject="#arguments.email.getSubject()#" 
					cc="#arguments.email.getCcEmail()#" 
					bcc="#arguments.email.getBccEmail()#" 
					replyto="#arguments.email.getReplyToEmail()#" 
				 	mailerid="#getNotificationConfigBean().getSmtpMailerId()#" 
				 	server="#getNotificationConfigBean().getSmtpServer()#" 
				 	charset="#getNotificationConfigBean().getSmtpCharset()#" 
				 	spoolenable="#getNotificationConfigBean().getSmtpSpoolEnabled()#" 
				 	type="#arguments.email.getEmailType()#">
#arguments.email.getBody()#
			</cfmail>
			<cfelse>
		 		<cfmail from="#arguments.email.getFromEmail()#" 
						to="#arguments.email.getToEmail()#" 
						subject="#arguments.email.getSubject()#" 
						cc="#arguments.email.getCcEmail()#" 
						bcc="#arguments.email.getBccEmail()#" 
						replyto="#arguments.email.getReplyToEmail()#" 
					 	mailerid="#getNotificationConfigBean().getSmtpMailerId()#" 
					 	server="#getNotificationConfigBean().getSmtpServer()#" 
					 	username="#getNotificationConfigBean().getSmtpUsername()#" 
					 	password="#getNotificationConfigBean().getSmtpPassword()#" 
					 	charset="#getNotificationConfigBean().getSmtpCharset()#" 
					 	spoolenable="#getNotificationConfigBean().getSmtpSpoolEnabled()#" 
					 	type="#arguments.email.getEmailType()#">
#arguments.email.getBody()#
				</cfmail>
		</cfif>
	</cffunction>

	<!--- EXCEPTION NOTIFICATION --->
	<cffunction name="sendExceptionEmail" access="public" returntype="void" output="false"
		hint="Sends an exception email to error email address.<br/>
		Throws: nothing">
		<cfargument name="appName" type="string" required="true" />
		<cfargument name="exception" type="machii.util.exception" required="true" />
		<cfargument name="mainEvent" type="string" required="false" default="not defined" />

		<cfset var tagCtxArr = arguments.exception.getTagContext() />
		<cfset var tagCtx = "" />
		<cfset var i = "" />
		<cfset var sc = "" />

		<cfsavecontent variable="sc">
		<cfoutput>
			<h1>#arguments.appName# - Exception Information</h1>
			<table>
				<tr>
					<td><h3>Main Event</h3></td>
					<td><p>#arguments.mainEvent#</p></td>
				</tr>
				<tr>
					<td><h3>Application Name</h3></td>
					<td><p>#arguments.appName#</p></td>
				</tr>
				<tr>
					<td><h3>Date/Time</h3></td>
					<td><p>#Now()#</p></td>
				</tr>
				<tr>
					<td><h3>Message</strong></td>
					<td><p>#arguments.exception.getMessage()#</p></td>
				</tr>
				<tr>
					<td><h3>Detail</strong></td>
					<td><p#arguments.exception.getDetail()#</p></td>
				</tr>
				<tr>
					<td><h3>Extended Info</h3></td>
					<td><p>#arguments.exception.getExtendedInfo()#</p></td>
				</tr>
				<tr>
					<td><h3>Tag Context</h3></td>
					<td>
						<ul>
							<cfloop index="i" from="1" to="#ArrayLen(tagCtxArr)#">
								<cfset tagCtx = tagCtxArr[i] />
								<li>#tagCtx["template"]# (#tagCtx["line"]#)</li>
							</cfloop>
						</ul>
					</td>
				</tr>
				<tr>
					<td><h3>Caught Exception</h3></td>
					<td><cfdump var="#arguments.exception.getCaughtException()#" expand="true" /></td>
				</tr>
			</table>
		</cfoutput>
		</cfsavecontent>
		
		<cfif getNotificationConfigBean().getSmtpUserName() is "" 
				and getNotificationConfigBean().getSmtpPassword() is "">
			<cfmail subject="#arguments.appName# - Exception Information"
				to="#getNotificationConfigBean().getEmailError()#"
				from="#getNotificationConfigBean().getEmailError()#"
				charset="#getNotificationConfigBean().getSmtpCharset()#"
				mailerid="#getNotificationConfigBean().getSmtpMailerID()#"
				server="#getNotificationConfigBean().getSmtpServer()#"
				spoolenable="#getNotificationConfigBean().getSmtpSpoolEnabled()#"
				type="html">
				<cfoutput>#trimTabs(sc)#</cfoutput>
			</cfmail>
		<cfelse>
			<cfmail subject="#arguments.appName# - Exception Information"
				to="#getNotificationConfigBean().getEmailError()#"
				from="#getNotificationConfigBean().getEmailError()#"
				charset="#getNotificationConfigBean().getSmtpCharset()#"
				mailerid="#getNotificationConfigBean().getSmtpMailerID()#"
				server="#getNotificationConfigBean().getSmtpServer()#"
				username="#getNotificationConfigBean().getSmtpUsername()#"
				password="#getNotificationConfigBean().getSmtpPassword()#"
				spoolenable="#getNotificationConfigBean().getSmtpSpoolEnabled()#"
				type="html">
				<cfoutput>#trimTabs(sc)#</cfoutput>
			</cfmail>
		</cfif>
	</cffunction>

	<!---
	PROTECTED FUNCTIONS
	--->
	<cffunction name="trimTabs" access="private" returntype="string" output="false"
		hint="Trims tabs from the input string<br/>
		Throws: nothing">
		<cfargument name="string" type="string" required="true" />
		<cfreturn Replace(arguments.string, chr(9) & chr(9) & chr(9), "", "ALL") />
	</cffunction>

</cfcomponent>